package test;

import java.util.TimerTask;
import java.util.concurrent.PriorityBlockingQueue;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: fzykd
 * Date: 2023-01-10
 * Time: 21:23
 */
//先描述 再组织
class MyTask implements Comparable<MyTask>{
    //布置的任务
    private Runnable runnable;
    //布置任务的事件
    private long time;

    //构造方法 构造任务
    public MyTask(Runnable runnable,long after){
        this.runnable = runnable;
        //布置任务的相对时间
        this.time = after + System.currentTimeMillis();
    }

    public void run() {
        this.runnable.run();
    }

    public long getTime() {
        return this.time;
    }

    //优先级队列 本质上是一个堆 那么堆就存在比较关系
    public int compareTo(MyTask o){
        return (int) (this.time - o.time);
    }
}


//在组织任务 在MyTimer里面组织任务
class MyTimer{
    //用一个数据解构来存在上面的任务 带有既有优先级 又阻塞 线程安全的阻塞队列
    private PriorityBlockingQueue<MyTask> queue = new PriorityBlockingQueue<>();

    //定时器当中有一个布置任务的方法 在这个方法当中 将任务存入到上述队列当中去
    public void schedule(Runnable runnable,long time){
        MyTask task = new MyTask(runnable,time);
        queue.put(task);
    }

    //设置锁对象
    private Object locker = new Object();

    //写一个构造方法 在构造方法中有一个检查线程 检查是否有时间到的 要执行
    public MyTimer(){
        Thread t = new Thread(()->{
            try {
                MyTask task = queue.take();
                long curTime = System.currentTimeMillis();
                //和现在时间比较
                if (task.getTime() > curTime){
                    //放回
                    queue.put(task);
                    //设置一个等待时间 避免忙等
                    synchronized (locker){
                        locker.wait(task.getTime() - curTime);
                    }
                }
                //否则 就执行
                task.run();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t.start();
    }

}

//实现自己版本的定时器
public class Demo5 {
    public static void main(String[] args) {
        MyTimer timer = new MyTimer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("自主实现的Timer");
            }
        },3000);
    }
}
